<?php
namespace API\Controller;

use Common\Tool\Tool;
use API\Model\OrderModel;
use Common\AlipayMobile\Lib\AlipayNotify;
use Common\UpacpApp\SDK\AcpService;
use Common\UpacpApp\SDK\LogUtil;
use Common\AlipayMobile\Lib\AopClient;
use Common\UpacpApp\SDK\SDKConfig;
use API\Model\OrderWxpayModel;

/**
 * 支付控制器 
 */
class PayOrderController extends BaseController implements SDKConfig
{
   
    //微信
    // 更改商户把相关参数后可测试【后续添加到系统配置中，请耐心等待】
    const APP_ID = '';
    
    const APP_SECRET = ""; // appsecret
    // 商户号，填写商户对应参数
    const MCH_ID = "";
    // 商户API密钥，填写相应参数
    const PARTNER_ID = "";
    const QQAPI      = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
    
    //银联
    const MERID = "802310054110819";
    
    // 支付结果回调页面
    
    public function __construct()
    {
        parent::__construct();
        
        Tool::checkPost($_POST, (array)null, false, array('token')) ? true : $this->ajaxReturnData(null, '400', '参数错误');
        $this->isLogin();
    }
    
    //支付宝接口
    public function index()
    {
        Tool::checkPost($_POST, array('is_numeric' => array('orders_num', 'price_shiji')), true , array('goods_title','orders_num','price_shiji')) ? true : $this->ajaxReturnData(null, '400', '参数错误');
       
        $body = $_POST['goods_title'];//商品描述
        //在支付接口中返回要用的支付数据
        //$alipayNotify = new AopClient();
        self::validateOrder($_POST['orders_num']);
        //组装系统参数
        $data = array(
            "app_id"        => C('appId') ,//appid
            "version"		=> "1.0",
            "format"		=> "json",
            "method"		=> "alipay.trade.app.pay",
            "timestamp"		=> date("Y-m-d H:i:s",time()),
            "charset"		=>"utf-8",
            "sign_type"     => "RSA", //无需修改
            "notify_url"	=> C('domain')."/API/PayOrder/alipayNotify",//回调地址
            "biz_content"	=> json_encode(array(
                "subject" 		=> $_POST['orders_num'],//商品名称
                "out_trade_no"	=> $_POST['orders_num'],//商户网站唯一订单号
                "total_amount"	=> $_POST['price_shiji'],//总金额
                "seller_id"		=>"2088421281806684",//支付宝账号
                "product_code"	=>"QUICK_MSECURITY_PAY",
                "timeout_express" =>"60m",
            )),
        );
        try {
            $privateKey = file_get_contents(C('rsa'));
        } catch (\Exception $e) {
            $this->ajaxReturnData(null, '400', '未知错误');
        }
        Tool::connect('Token');
        $data = Tool::alipayToken($data, $privateKey);
        $code    = empty($data) ? '400' : '200';
        $message = empty($data) ? '支付失败': '订单支付中';
        echo json_encode(array(
            'message' => $message,
            'code'    => $code,
            'data'    => $data
        ));die();
    }
    
    /**
     * 支付通知 
     */
    public function alipayNotify()
    {
        $alipayNotify = new AopClient();
       
        $verify_result = $alipayNotify->rsaCheckV1($_POST,PRV);
        //file_put_contents("./10.txt",$verify_result);
        if($verify_result) {//验证成功
            //获取支付宝的通知返回参数，可参考技术文档中服务器异步通知参数列表
            //商户订单号
            $out_trade_no = $_POST['out_trade_no'];
            //支付宝交易号
            $trade_no = $_POST['trade_no'];
            //交易状态
            $trade_status = $_POST['trade_status'];
            if($_POST['trade_status'] == 'TRADE_FINISHED') {
        
            } else if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理，根据订单号（out_trade_no）在商户网站的订单系统中查到该笔订单的详细，并执行商户的业务程序
                //请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的
                //如果有做过处理，不执行商户的业务程序
                //注意：
                //退款日期超过可退款期限后（如三个月可退款），支付宝系统发送该交易状态通知
                //调试用，写文本函数记录程序运行情况是否正常
                //logResult("这里写入想要调试的代码变量值，或其他运行的结果记录");
                $orders_num =$out_trade_no;
                $info_a = strpos($orders_num,'u');
                if($info_a==1){
                    //提成处理
                }else{
                    //修改商品
                    //修改数据库中的订单状态.1已支付
                    OrderModel::getInitation()->save(array(
                        'order_status' => 1
                    ),array(
                        'where' => array('user_id' => $_SESSION['userId'], 'order_sn_id' => $orders_num )
                    ));
                }
            }
            echo "success";
        }else{
            //验证失败
            echo "fail";
            //调试用，写文本函数记录程序运行情况是否正常
            //logResult("这里写入想要调试的代码变量值，或其他运行的结果记录");
        }
    }
    
    // 微信支付接口
    public function wxPay()
    {
        Tool::checkPost($_POST, array('is_numeric' => array('out_trade_no','total_fee')),true,array( 'body', 'total_fee','out_trade_no')) ?true :$this->ajaxReturnData(null, '400', '参数错误');
        
        self::validateOrder($_POST['out_trade_no']);
        
        $wxPay = 'wx_'.Tool::connect('Token')->toGUID();
        
        $status = OrderWxpayModel::getInitation()->add(array(
            'order_id'  => $_POST['out_trade_no'],
            'wx_pay_id' => 'wx_'.Tool::toGUID()
        ));
        $this->prompt($status, null, '支付失败', false);
        
        // 支付结果回调页面
        $NOTIFY_URL = C('domain').'/API/Nofity/wxNotify';
        
        // STEP 1. 构造一个订单。
        $order = array(
            "body"          => $_POST['body'],
            "appid"         => self::APP_ID,
            "mch_id"        => self::MCH_ID,
            "nonce_str"     => mt_rand(),
            "notify_url"    => $NOTIFY_URL,
            "out_trade_no"  => $wxPay.'-'.$_POST['out_trade_no'],
            "spbill_create_ip" => $_SERVER['REMOTE_ADDR'],
            "total_fee" => ($_POST['total_fee'] * 100), // 坑！！！这里的最小单位时分，跟支付宝不一样。1就是1分钱。只能是整形。
            "trade_type" => "APP"
        );
        
        Tool::connect('Token');
        
        $result = Tool::wx($order, self::QQAPI, self::PARTNER_ID);
        
        
        // 使用$result->nonce_str和$result->prepay_id。再次签名返回app可以直接打开的链接。
        $data = array(
            "noncestr" => "" . $result->nonce_str,
            "prepayid" => "" . $result->prepay_id, // 上一步请求微信服务器得到nonce_str和prepay_id参数。
            "appid" => self::APP_ID,
            "package" => "Sign=WXPay",
            "partnerid" => self::MCH_ID,
            "timestamp" => time()
        );
        ksort($data);
        $sign = "";
        foreach ($data as $key => $value) {
            if ($value && $key != "sign" && $key != "key") {
                $sign .= $key . "=" . $value . "&";
            }
        }
        $sign .= "key=" . self::PARTNER_ID;
        $sign = strtoupper(md5($sign));
        $data['sign'] = $sign;
    
       $this->updateClient($data, '操作');
    }
   
   
    private  function validateOrder($order)
    {
        $order = OrderModel::getInitation()->getGoodsByOrderSn($order);
        $this->prompt($order, null, '没有该订单或商品价格错误');
    }
    
    // 银联支付
    public function  ylPay()
    {
        Tool::checkPost($_POST, array('is_numeric' => array('orders_num', 'price_shiji')),true,array( 'price_shiji', 'orders_num')) ?true :$this->ajaxReturnData(null, '400', '参数错误');
        
        // 判断是否存在该订单
        self::validateOrder($_POST['orders_num']);
        $domin = C('domain');
        $params = array(
            'merId' => self::MERID, // 商户代码，请改自己的测试商户号，此处默认取demo演示页面传递的参数
            'orderId' => $_POST['orders_num'], // 商户订单号，8-32位数字字母，不能含“-”或“_”，此处默认取demo演示页面传递的参数，可以自行定制规则
            'txnTime' => date("YmdHis"), // 订单发送时间，格式为YYYYMMDDhhmmss，取北京时间，此处默认取demo演示页面传递的参数
            'txnAmt' => $_POST['price_shiji'] * 100, // 交易金额，单位分，此处默认取demo演示页面传递的参数
            // 'reqReserved' =>'透传信息', //请求方保留域，透传字段，查询、通知、对账文件中均会原样出现，如有需要请启用并修改自己希望透传的数据
            // 以下信息非特殊情况不需要改动
            'version' => '5.0.0', // 版本号
            'encoding' => 'utf-8', // 编码方式
            'txnType' => '01', // 交易类型
            'txnSubType' => '01', // 交易子类
            'bizType' => '000201', // 业务类型
            'frontUrl' => $domin.'/API/PayOrder/ylNotify', // 前台通知地址
            'backUrl' =>  $domin.'/API/PayOrder/ylNotify', // 后台通知地址
            'signMethod' => '01', // 签名方法
            'channelType' => '08', // 渠道类型，07-PC，08-手机
            'accessType' => '0', // 接入类型
            'currencyCode' => '156'// 交易币种，境内商户固定156
        ) ;
    
        AcpService::sign($params); // 签名
      
        
        $data = AcpService::post($params, self::SDK_App_Request_Url);
        
        if (count($data) <= 0) { // 没收到200应答的情况
           LogUtil::printResult(self::SDK_App_Request_Url, $params, "");
           $this->ajaxReturnData(null,'400','支付失败');
        }
        $this->updateClient($data,'支付');
    }
    
    /**
     * 银联返回通知 
     */
    public function ylNotify()
    {
        if (empty($_POST['signature']))
        {
            echo '签名为空';
        }
        
        echo AcpService::validate($_POST) ? '验签成功' : '验签失败';
        $orders_num = $_POST['orderId']; // 其他字段也可用类似方式获取
        $respCode = $_POST['respCode']; // 判断respCode=00或A6即可认为交易成功
    
        if ($respCode == '00' || $respCode == 'A6') 
        {
             $status =  OrderModel::getInitation()->save(array(
                'order_status' => OrderModel::YesPaid
                ), array(
                    'where' => array('order_sn_id' => $orders_num)
               ));
        }
    }
}